﻿using Libs;
using Libs.Egucha;
using System.Collections.Generic;
using System.Text;
using WriteForFighting.FightingAPI;
using WriteForFighting.Game.Asset;
using WriteForFighting.Game.Entity.Effect;

namespace WriteForFighting.Game.Entity
{
    class EntityPlayer : EntityBase
    {
        public Player Player { get; private set; }
        public string PlayerProgramPath { get; private set; }
        public int PlayerType { get; private set; }

        private const int HealthBarMaxLong = 60;

        private static int colorNameBack = DX.GetColor(255, 255, 255);
        private static int colorNameString = DX.GetColor(0, 0, 0);
        private static int colorHealthBarEdge = DX.GetColor(0, 0, 0);
        private static int colorHealthBar = DX.GetColor(0, 0, 255);

        private EntityManager entityBulletsManager;
        private string playerName;
        private int playerNameStringLong;
        private bool isRequestedToLanchABullet;

        public EntityPlayer(double par1X, double par2Y, double par3Angle, string par4PlayerProgramPath,
            EntityManager par5EntityBulletsManager, int par6PlayerType = 0)
            : base(par1X, par2Y, par3Angle)
        {
            CollisionCircleRadius = 12;
            CollisionBoxRelativeX = 0;
            CollisionBoxRelativeY = 5;
            MaxHealth = 5;
            Health = 5;

            PlayerProgramPath = par4PlayerProgramPath;
            Player = PlayerAssemblyLoader.GetPlayerInstanceFromAssembly(PlayerProgramPath);
            entityBulletsManager = par5EntityBulletsManager;
            PlayerType = par6PlayerType;

            PlayerProgramAttribute attribute = PlayerAssemblyLoader.GetPlayerInfo(Player);
            playerName = attribute.Name;
            playerNameStringLong = Encoding.GetEncoding("Shift_JIS").GetByteCount(playerName) * 6;
        }

        protected override void OnUpdate(int par1GameTickCount, EntityManager par2PlayersManager,
            EntityManager par3BulletsManager, EntityManager par4EffectsManager)
        {
            Rudder rudder = new Rudder();
            EntityInfo playerInfo = new EntityInfo(X, Y, Angle, MaxHealth, Health);
            EntityInfo enemyInfo = new EntityInfo(0, 0, 0, 0, 0);

            foreach (EntityPlayer e in par2PlayersManager.Entities)
            {
                if ((e != null) &&
                    (e != this))
                {
                    if (e.IsDeath) { break; }
                    enemyInfo = new EntityInfo(e.X, e.Y, e.Angle, e.MaxHealth, e.Health);
                    break;
                }
            }

            Player.Update(playerInfo, enemyInfo, GetEnemyBulletsInfo(), rudder, Age);

            Angle += rudder.AngleMoveSpeed;
            vector.x = 0;
            vector.y = Rudder.MaxMoveSpeed * -rudder.MoveSpeed;
            vector.RotateVector(Angle);

            if (rudder.IsRequestedToLanchABullet)
            {
                isRequestedToLanchABullet = true;
            }

            if ((isRequestedToLanchABullet) &&
                ((Age % 30) == 0))
            {
                isRequestedToLanchABullet = false;

                EntityBullet bullet;

                {
                    Vector tv = new Vector(0, -13);
                    tv.RotateVector(Angle);
                    bullet = new EntityBullet(X + tv.x, Y + tv.y, Angle, this);
                }
                {
                    Vector bv = new Vector();
                    bv.y = -1.75;
                    bv.RotateVector(Angle);
                    bullet.vector = bv;
                    DX.PlaySoundMem(Sound.Shoot, DX.DX_PLAYTYPE_BACK);
                    par3BulletsManager.SpawnEntity(bullet);
                }
            }
        }

        protected override void OnDraw(int par1GameTickCount)
        {
            DX.DrawRotaGraph2F((float)X, (float)Y, 30.5f, 30.0f, 1.0d, Angle, Drawable.Players[0], DX.TRUE);

            //名前のバック
            DX.SetDrawBlendMode(DX.DX_BLENDMODE_ALPHA, 100);
            DX.DrawBox((int)X - (playerNameStringLong / 2), (int)Y + 18, (int)X + (playerNameStringLong / 2), (int)Y + 18 + 12, colorNameBack, DX.TRUE);
            DX.SetDrawBlendMode(DX.DX_BLENDMODE_NOBLEND, 0);

            DX.DrawStringFToHandle((float)X - (playerNameStringLong / 2), (float)Y + 18, playerName, colorNameString, Font.GosickNormalAA);

            //体力ゲージの枠
            DX.DrawBox((int)(X - HealthBarMaxLong / 2) - 1, (int)Y + 32 - 1, (int)(X + HealthBarMaxLong / 2) + 1, (int)Y + 32 + 2 + 1, colorHealthBarEdge, DX.FALSE);
            if ((0 < Health) &&
                (Health != InfinityHealth))
            {
                int healthBarLong = (int)(HealthBarMaxLong * Health / MaxHealth);
                DX.DrawBox((int)(X - HealthBarMaxLong / 2), (int)Y + 32, (int)(X - HealthBarMaxLong / 2) + healthBarLong, (int)Y + 32 + 2, colorHealthBar, DX.TRUE);
            }
        }

        protected override void OnDeath(int par1GameTickCount, EntityManager par2PlayersManager,
            EntityManager par3BulletsManager, EntityManager par4EffectsManager)
        {
            par4EffectsManager.SpawnEntity(new EntityEffectExplosion(X, Y, false));
        }

        private EntityInfo[] GetEnemyBulletsInfo()
        {
            List<EntityInfo> enemyBulletsInfo = new List<EntityInfo>();

            foreach (EntityBase e in entityBulletsManager.Entities)
            {
                if ((e is EntityBullet) &&
                    (!e.IsDeath))
                {
                    enemyBulletsInfo.Add(new EntityInfo(e.X, e.Y, e.Angle, e.MaxHealth, e.Health));
                }
            }

            return enemyBulletsInfo.ToArray();
        }
    }
}
